package com.fingard.dsp.bank.directbank.nnbill01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.allinpay.ets.client.StringUtil;
import com.bill99.schema.commons.Version;
import com.bill99.schema.fo.commons.RequestHeader;
import com.bill99.schema.fo.commons.SealDataType;
import com.bill99.schema.fo.settlement.SettlementPkiApiRequest;
import com.bill99.schema.fo.settlement.SettlementPkiRequestType;
import com.bill99.sdk.crypto.process.CryptoProcessorFactory;
import com.bill99.sdk.crypto.schema.CmsSignedAndEnveloped;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.nnbill01.util.Cons;
import com.fingard.dsp.bank.directbank.nnbill01.util.HttpsClientFactory;
import com.fingard.dsp.bank.directbank.nnbill01.util.MerchantPKIUtils;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.balancedetail.*;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.batch.CustomerUtil;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.batch.DealInfoEntity;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.batch.StringUtils;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.gatewayrefund.dto.GatewayRefundQueryResponse;
import com.fingard.net.WebRequest;
import com.fingard.text.AESHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.SortHelper;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.GZIPOutputStream;

public class NNBill01Base extends DirectBase {
    protected String getCharset() {
        return getBankConfig().getCharset("UTF-8");
    }

    private final String ENCODING = "utf-8";

    protected String getCharset(String p_def, String p_for) {
        return getBankConfig().getCharset(p_def, p_for);
    }

    /**
     * 生成16个字符
     */
    protected byte[] randomKey() throws Exception {
        String randomStr = String.format("%d", new Random().nextLong());
        String randomKeyStr = randomStr.substring(1, 17);

        return randomKeyStr.getBytes(getCharset());
    }

    public String signMsg(String signMsg, String ownKeyStorePath, String ownKeyPassword) throws Exception {
        String base64 = "";
        FileInputStream ksfis = null;
        BufferedInputStream ksbufin = null;
        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            String file = ownKeyStorePath.replaceAll("%20", " ");
            ksfis = new FileInputStream(file);
            ksbufin = new BufferedInputStream(ksfis);
            char[] keyPwd = ownKeyPassword.toCharArray();
            ks.load(ksbufin, keyPwd);
            File file1 = new File(file);
            String ownKeyName = file1.getName();
            PrivateKey priK = (PrivateKey) ks.getKey(ownKeyName.replaceAll(".pfx", ""), keyPwd);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(priK);
            signature.update(signMsg.getBytes(getCharset()));
            sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
            base64 = encoder.encode(signature.sign());
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        } finally {
            if (ksbufin != null) {
                ksbufin.close();
            }
            if (ksfis != null) {
                ksfis.close();
            }
        }
        return base64;
    }

    /**
     * RSA私钥签名 签名摘要SHA1
     * -- 生成签名
     */
    public byte[] signByRSA(byte[] originalBytes, ActSetItem actItem) throws Exception {
        RSAHelper rsaHelper = new RSAHelper();
        PrivateKey localPrivKey = rsaHelper.getPrivateKeyFromPfx(actItem.ownKeyStorePath, actItem.ownKeyPassword);
        PublicKey peerPubKey = rsaHelper.getPublicKeyFromCer(actItem.oppCertFilePath);
        rsaHelper.initKey(localPrivKey, peerPubKey);
        byte[] signBytes = rsaHelper.signRSA256(originalBytes, false, getCharset());

        return signBytes;
    }

    /**
     * RSA公钥验签 签名摘要SHA1
     * -- 验签结果
     */
    protected boolean verifyByRSA(byte[] originalBytes, byte[] signBytes, ActSetItem actItem) throws Exception {
        RSAHelper rsaHelper = new RSAHelper();
        PrivateKey localPrivKey = rsaHelper.getPrivateKeyFromPfx(actItem.ownKeyStorePath, actItem.ownKeyPassword);
        PublicKey peerPubKey = rsaHelper.getPublicKeyFromCer(actItem.oppCertFilePath);
        rsaHelper.initKey(localPrivKey, peerPubKey);
        boolean verifyResult = rsaHelper.verifyRSA256(originalBytes, signBytes, false, getCharset());

        return verifyResult;
    }

    /**
     * RSA公钥加密
     * -- 生成数字信封
     */
    protected byte[] encryptByPKRSA(byte[] originalBytes, ActSetItem actItem) throws Exception {
        RSAHelper rsaHelper = new RSAHelper();
        PrivateKey localPrivKey = rsaHelper.getPrivateKeyFromPfx(actItem.ownKeyStorePath, actItem.ownKeyPassword);
        PublicKey peerPubKey = rsaHelper.getPublicKeyFromCer(actItem.oppCertFilePath);
        rsaHelper.initKey(localPrivKey, peerPubKey);
        byte[] encryptBytes = rsaHelper.encryptRSA(originalBytes, false, getCharset());

        return encryptBytes;
    }

    /**
     * RSA私钥解密
     * -- -- 解密数字信封
     */
    public byte[] decryptByPKRSA(byte[] originalBytes, ActSetItem actItem) throws Exception {
        RSAHelper rsaHelper = new RSAHelper();
        PrivateKey localPrivKey = rsaHelper.getPrivateKeyFromPfx(actItem.ownKeyStorePath, actItem.ownKeyPassword);
        PublicKey peerPubKey = rsaHelper.getPublicKeyFromCer(actItem.oppCertFilePath);
        rsaHelper.initKey(localPrivKey, peerPubKey);
        byte[] encryptBytes = rsaHelper.decryptRSA(originalBytes, false, getCharset());

        return encryptBytes;
    }

    public byte[] gzip(byte[] b1) {
        byte[] b = null;
        ByteArrayOutputStream bo = null;
        GZIPOutputStream gzipo = null;
        try {
            bo = new ByteArrayOutputStream();
            gzipo = new GZIPOutputStream(bo);
            gzipo.write(b1);
            gzipo.finish();
            b = bo.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (gzipo != null)
                    gzipo.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (bo != null)
                    bo.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return b;
    }

    /**
     * 返回HTTP字符串转MAP
     *
     * @param
     * @return
     */
    public static Map<String, String> convertToMap(String srcStr) {
        Map<String, String> params = new HashMap<String, String>();

        String[] nodes = srcStr.split("&");
        for (String node : nodes) {
            int index = node.indexOf("=");

            String key = node.substring(0, index);
            String value = node.substring(index + 1);

            params.put(key, value);
        }

        return params;
    }

    /**
     * 快钱人民币网关支付通知返回验证签名
     *
     * @param returnStr  验签原始请求串
     * @param serverSign 服务器返回签名串
     * @param actItem    商户配置
     * @return 验签结果
     */
    public boolean verifyRMBGW(String returnStr, String serverSign, ActSetItem actItem) throws IOException {
        FileInputStream fis1 = null;
        try {
            X509Certificate cert = null;
            fis1 = new FileInputStream(actItem.oppCertFilePath);

            WriteBankLogLn2("快钱证书路径:" + actItem.oppCertFilePath);

            CertificateFactory cf = CertificateFactory.getInstance("X509");
            cert = (X509Certificate) cf.generateCertificate(fis1);
            PublicKey publicKey = cert.getPublicKey();

            Signature signature = Signature.getInstance("SHA1withRSA");
            signature.initVerify(publicKey);
            signature.update(returnStr.getBytes());
            return signature.verify(new BASE64Decoder().decodeBuffer(serverSign));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis1 != null) {
                fis1.close();
            }
        }

        return false;
    }

    /**
     * 快钱人民币网关支付通知返回验证签名
     *
     * @param returnStr  验签原始请求串
     * @param serverSign 服务器返回签名串
     * @param actItem    商户配置
     * @return 验签结果
     */
    public boolean enCodeByCer(String returnStr, String serverSign, ActSetItem actItem) throws IOException {
        FileInputStream inStream = null;
        try {
            inStream = new FileInputStream(actItem.oppCertFilePath);

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);

            PublicKey pk = cert.getPublicKey();

            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(pk);
            signature.update(returnStr.getBytes());

            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            return signature.verify(decoder.decodeBuffer(serverSign));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inStream != null) {
                inStream.close();
            }
        }
        return false;
    }

    public String convertMapToStr(LinkedHashMap<String, String> params) {
        String reqStr = "";

        for (String key : params.keySet()) {
            if (!params.get(key).equals("")) {
                if (reqStr.length() > 0) {
                    reqStr += "&";
                }

                reqStr += key + "=" + params.get(key);
            }
        }

        return reqStr;
    }

    /**
     * 将MAP转换为post请求串
     *
     * @param returns
     * @param paramId
     * @param paramValue
     * @return
     */
    public String appendParam(String returns, String paramId, String paramValue) {
        if (returns != "") {
            if (paramValue != "") {
                returns += "&" + paramId + "=" + paramValue;
            }
        } else {
            if (paramValue != "") {
                returns = paramId + "=" + paramValue;
            }
        }

        return returns;
    }

    /**
     * 获取签名原数据
     *
     * @param returns
     * @param paramId
     * @param paramValue
     * @return
     */
    public String appendParams(String returns, String paramId, String paramValue) {
        if (returns != "") {
            if (paramValue != "") {
                returns += paramId + "=" + paramValue;
            }
        } else {
            if (paramValue != "") {
                returns = paramId + "=" + paramValue;
            }
        }

        return returns;
    }

    public String convertParams(GatewayRefundQueryResponse queryResponse) {

        String returns = "version=" + queryResponse.getVersion() + "&signType=" + queryResponse.getSignType() + "&merchantAcctId=" + queryResponse.getMerchantAcctId()
                + "&recordCount=" + queryResponse.getRecordCount() + "&pageSize=" + queryResponse.getPageSize() + "&signMsg=" + queryResponse.getSignMsg()
                + "&pageCount=" + queryResponse.getPageCount() + "&currentPage=" + queryResponse.getCurrentPage() + "&errcode=" + queryResponse.getErrCode();
        return returns;
    }

    /**
     * 获取验签原始串及签名
     * retStr[0]:验签原始串
     * retStr[1]:签名
     *
     * @param p_reqStr
     * @return
     */
    public static String[] getServerSign(String p_reqStr) {
        String[] retStr = new String[]{"", ""};

        retStr[0] = p_reqStr.substring(0, p_reqStr.lastIndexOf("&"));

        String[] respArray = p_reqStr.split("&");
        for (String str : respArray) {
            if (str.indexOf("signMsg") != -1) {
                retStr[1] = str.substring(str.indexOf("=") + 1);
            }
        }

        return retStr;
    }

    public String readExcel(String filepath) throws Exception {
        try {
            Workbook wb = new HSSFWorkbook(new FileInputStream(filepath));
            Sheet sheet = wb.getSheetAt(0);

            Row totalRow = sheet.getRow(5);
            String totalNum = getCellValue(totalRow.getCell(1));

            StringBuilder sbFileContent = new StringBuilder();
            for (int i = 9; i < 9 + Integer.parseInt(totalNum); i++) {
                Row detailRow = sheet.getRow(i);
                if (detailRow == null) {// 略过空行
                    continue;
                }
                int cellSize = detailRow.getLastCellNum();
                StringBuilder eachline = new StringBuilder();
                for (int k = 0; k < cellSize; k++) {
                    Cell cell = detailRow.getCell(k);
                    if (eachline.length() > 0) {
                        eachline.append(",");
                    }
                    eachline.append(getCellValue(cell));
                }
                sbFileContent.append(eachline).append("\r\r\n");
            }
            return sbFileContent.toString();
        } catch (FileNotFoundException e) {
            throw e;
        }
    }

    public static String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }

        //把数字当成String来读，避免出现1读成1.0的情况  
        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                Date theDate = cell.getDateCellValue();
                SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                cellValue = dff.format(theDate);
            } else {
                cell.setCellType(Cell.CELL_TYPE_STRING);
            }
        }

        //判断数据的类型  
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC: //数字
                if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                    Date theDate = cell.getDateCellValue();
                    SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    cellValue = dff.format(theDate);
                } else {
                    cellValue = String.valueOf(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_STRING: //字符串  
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN: //Boolean  
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA: //公式  
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case Cell.CELL_TYPE_BLANK: //空值   
                cellValue = "";
                break;
            case Cell.CELL_TYPE_ERROR: //故障  
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    public Map<String, String> removeHead(Map<String, String> tmpMapParams) {
        tmpMapParams.remove("BankCode");
        tmpMapParams.remove("TransType");
        tmpMapParams.remove("CommandCode");
        tmpMapParams.remove("Entity");
        return tmpMapParams;
    }

    protected String getSignStr(Map<String, String> mapParams) {
        Map<String, String> signMap = new HashMap<String, String>();

        for (Map.Entry<String, String> entry : mapParams.entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();

            if (StringHelper.hasAnyChar(value)) {
                signMap.put(name, value);
            }
        }

        // Map排序
        signMap = SortHelper.sortMapByName(signMap);

        // Map转HTTP字符串
        String signStr = "";
        for (String key : signMap.keySet()) {
            signStr += "&" + key + "=" + signMap.get(key);
        }
        signStr = signStr.substring(1);

        return signStr;
    }

    protected String[] sendToBank(String sendMsg, String url) throws Exception {
        String[] retStr;
        WriteBankUrlLogLn(url + "?" + sendMsg);
        WriteBankLogStep2(sendMsg);
        String sendInfo = url + "?" + sendMsg;
        WebRequest tmpWebRequest = new WebRequest(sendInfo);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("connection", "Close");
//        byte[] tmpUpBytes = sendMsg.getBytes(getCharset());
        retStr = tmpWebRequest.upload(null, "UTF-8");
        WriteBankLogStep3(retStr[1]);
        if (retStr[0].length() == 0) {
            int tmpIndex = retStr[1].indexOf("{");
            if (tmpIndex > 0) {
                retStr[1] = retStr[1].substring(tmpIndex);
            }
        } else {
            this.WriteBankLogLn(tmpWebRequest.sbLog);
        }
        return retStr;
    }

    protected String[] sendDataToBank(ActSetItem actItem, JSONObject reqJson, String url) throws Exception {
        final String[] retStr = new String[]{"", ""};
        CloseableHttpClient httpClient = null;
        try {

            WriteBankLogLn2("加密前报文明文数据:\r\r\n" + JSON.toJSONString(reqJson));
            String kuaiqianPublicCertFile = actItem.ownCertFilePath;
            String MerchantPrivateCertFile = actItem.ownKeyStorePath;
            CryptoProcessorFactory.initCertDir(kuaiqianPublicCertFile);
            CryptoProcessorFactory.initCertDir(MerchantPrivateCertFile);
            CmsSignedAndEnveloped encryptObj = MerchantPKIUtils.encrypt(kuaiqianPublicCertFile, MerchantPrivateCertFile, reqJson.getJSONObject(Cons.BODY).toJSONString());

            if (StringHelper.isNullOrEmpty(encryptObj.getSignedData()) || StringHelper.isNullOrEmpty(encryptObj.getEnvelopedData())) {
                retStr[0] = "-1";
                retStr[1] = "PKI加密后相关字段为空";
                return retStr;
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(Cons.REQUEST_BODY, encryptObj);
            jsonObject.put(Cons.HEAD, reqJson.getJSONObject(Cons.HEAD));
            WriteBankLogStep2(JSON.toJSONString(jsonObject));

            WriteBankUrlLogLn(url);
            HttpPost httpPost = new HttpPost(url);
            if (url.startsWith("https")) {
                httpClient = createHttpsClient(actItem.inMerchantId, actItem);
            } else {
                httpClient = HttpClients.createDefault();// 兼容没有开启SSL认证
            }
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(new StringEntity(JSON.toJSONString(jsonObject), Consts.UTF_8));
            String resp = httpClient.execute(httpPost, new ResponseHandler<String>() {
                @Override
                public String handleResponse(HttpResponse httpresponse) throws ClientProtocolException, IOException {
                    int statusCode = httpresponse.getStatusLine().getStatusCode();
                    WriteBankLogLn("resp-httpstatus=" + statusCode);
                    String entityStr = "";
                    HttpEntity entity = httpresponse.getEntity();
                    if (entity != null) {
                        entityStr = EntityUtils.toString(entity, Consts.UTF_8);
                    }
                    retStr[1] = entityStr;
                    return entityStr;
                }
            });
            WriteBankLogStep3(resp);
            return retStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (httpClient != null) {
                httpClient.close();
            }
        }
    }

    public CloseableHttpClient createHttpsClient(String memberCode, ActSetItem actItem) throws Exception {
        FileInputStream propFileInputStream = null;
        FileInputStream keystoreFileInputStream = null;
        try {
            String sslCertsDir = actItem.oppCertFilePath;
            if (StringUtil.isEmpty(sslCertsDir)) {
                throw new Exception("请勿删除properties相关配置信息[" + Cons.SSL_CERTS_DIR + "]");
            }
            WriteBankLogLn("ssl certs dir=" + sslCertsDir);
            File dirFile = new File(sslCertsDir);
            if (sslCertsDir.startsWith("classpath:")) {// 兼容项目CLASSPATH目录下
                sslCertsDir = sslCertsDir.substring(10);
                URL url = NNBill01Base.class.getClassLoader().getResource(sslCertsDir);
                dirFile = new File(url.toURI());
            }
            if (!dirFile.isDirectory()) {
                throw new Exception("SSL证书路径配置有误(精确到目录层)");
            }
            //
            File[] fileList = dirFile.listFiles();
            if (fileList.length == 0) {
                throw new Exception("未找到SSL证书");
            }
            //
            File sslFile = null;
            for (int i = 0; i < fileList.length; i++) {
                File item = fileList[i];
                String fileFullName = item.getName();
                String fileSuffix = fileFullName.substring(fileFullName.lastIndexOf(".") + 1, fileFullName.length());
                String fileName = fileFullName.substring(0, fileFullName.lastIndexOf("."));
                // 仅支持JKS/PFX文件
                if (fileName.equals(memberCode)
                        && ("jks".equalsIgnoreCase(fileSuffix) || "pfx".equalsIgnoreCase(fileSuffix))) {
                    sslFile = item;
                    break;
                }
            }
            if (sslFile == null) {
                throw new Exception("未找到SSL证书");
            }
            WriteBankLogLn("ssl file name=" + sslFile.getName());
            //
            File sslPropFile = new File(sslFile.getParent(), sslFile.getName() + ".properties");
            if (!sslPropFile.exists()) {
                throw new Exception("未找到SSL证书对应的properties文件");
            }
            WriteBankLogLn("ssl properties file name=" + sslPropFile.getName());
            propFileInputStream = new FileInputStream(sslPropFile);
            Properties props = new Properties();
            props.load(propFileInputStream);
            String password = null;
            String passwordKey = "storepass";//请勿修改，否则无法加载SSL证书的密码
            if (StringUtil.isEmpty(passwordKey)) {
                throw new Exception("请勿删除properties相关配置信息[" + Cons.PASSWORD_KEY + "]");
            }
            for (Object key : props.keySet()) {
                String name = key.toString();
                String value = String.valueOf(props.get(name));
                if (name.equals(passwordKey)) {
                    password = value;
                    break;
                }
            }
            WriteBankLogLn("ssl file password=" + password);
            String insType = "JKS";
            if (sslFile.getName().endsWith(".pfx")) {
                insType = "PKCS12";
            }
            KeyStore keyStore = KeyStore.getInstance(insType);
            keystoreFileInputStream = new FileInputStream(sslFile);
            if (StringUtil.isEmpty(password)) {
                keyStore.load(keystoreFileInputStream, null);
            } else {
                keyStore.load(keystoreFileInputStream, password.toCharArray());
            }
            //
            HttpsClientFactory factory = new HttpsClientFactory();
            factory.setKeyStore(keyStore);
            factory.setKeyStorePwd(password);
            //
            String soTimeout = "60000";
            String connTimeout = "60000";
            String sslVersion = "TLSv1.2";
            if (StringUtil.isEmpty(soTimeout) || StringUtil.isEmpty(connTimeout) || StringUtil.isEmpty(sslVersion)) {
                throw new Exception("请勿删除properties相关配置信息[" + Cons.SO_TIMEOUT + "/" + Cons.CONN_TIMEOUT + "/"
                        + Cons.SSL_VERSION + "]");
            }
            factory.setConnTimeout(Integer.parseInt(connTimeout));
            factory.setSoTimeout(Integer.parseInt(soTimeout));
            factory.setSSLVersion(sslVersion);
            return factory.createSSLClient();
        } catch (Exception e) {
            throw e;
        } finally {
            if (keystoreFileInputStream != null) {
                keystoreFileInputStream.close();
            }
            if (propFileInputStream != null) {
                propFileInputStream.close();
            }
        }
    }

    public String requestOriginalData(DetailApiRequestType requestType, String key) {
        StringBuffer sb = new StringBuffer();
        sb.append("&requestTime=").append(this.null2String(requestType.getRequestTime())).append("&startTime=").append(this.null2String(requestType.getStartTime())).append("&endTime=").append(this.null2String(requestType.getEndTime())).append("&memberCode=").append(this.null2String(requestType.getMemberCode())).append("&mbrAcctCode=").append(this.null2String(requestType.getMbrAcctCode())).append("&pageNo=").append(this.null2String(requestType.getPageNo())).append("&pageSize=").append(this.null2String(requestType.getPageSize())).append("&key=").append(this.null2String(key));
        return sb.toString();
    }

    public String responseOriginalData(DetailApiResponseType responseType, String key) {
        StringBuffer sb = new StringBuffer();
        sb.append("&requestTime=").append(this.null2String(responseType.getRequestTime())).append("&responseTime=").append(this.null2String(responseType.getResponseTime())).append("&startTime=").append(this.null2String(responseType.getStartTime())).append("&endTime=").append(this.null2String(responseType.getEndTime())).append("&memberCode=").append(this.null2String(responseType.getMemberCode())).append("&mbrAcctCode=").append(this.null2String(responseType.getMbrAcctCode())).append("&pageNo=").append(this.null2String(responseType.getPageNo())).append("&pageSize=").append(this.null2String(responseType.getPageSize())).append("&totalPay=").append(this.null2String(responseType.getTotalPay())).append("&totalIncome=").append(this.null2String(responseType.getTotalIncome())).append("&totalCount=").append(this.null2String(responseType.getTotalCount())).append("&totalPage=").append(this.null2String(responseType.getTotalPage())).append("&key=").append(this.null2String(key));
        return sb.toString();
    }

    public String null2String(String str) {
        return str == null ? "" : str;
    }

    public BalanceDetailResponse balanceDetailFormWS(BalanceDetailRequest balanceDetailRequest) {
        try {
            String url = bankFront.getUrl("queBalDetail");
            URL wsdlUrl = new URL(url);
            BalancedetailSoap11Stub service = (BalancedetailSoap11Stub) (new BalancedetailServiceLocator()).getBalancedetailSoap11(wsdlUrl);
            service.setTimeout(60000);
            BalanceDetailResponse result = service.balanceDetail(balanceDetailRequest);
            return result;
        } catch (Exception var5) {
            var5.printStackTrace();
            return null;
        }
    }


    public String apply_ws(DealInfoEntity dealInfo, ActSetItem actItem, String url) {
        return doit(getSettlementPkiApiRequest(dealInfo, actItem), url);
    }

    protected String getSettlementPkiApiRequest(DealInfoEntity dealInfo, ActSetItem actItem) {
        String postContent = null;
        SettlementPkiApiRequest request = new SettlementPkiApiRequest();
        RequestHeader head = new RequestHeader();
        Version ve = new Version();
        head.setTime(Format.DateTime17Format.format(new Date()));
        ve.setService(dealInfo.getServiceType());
        ve.setVersion(dealInfo.getVersion());
        head.setVersion(ve);
        request.setRequestHeader(head);
        SettlementPkiRequestType body = new SettlementPkiRequestType();
        try {
            body.setMemberCode(dealInfo.getMemberCode());
            SealDataType sealdata = new SealDataType();
            String type = dealInfo.getServiceType();
            String originalData = "";
            if ("fo.batch.settlement.batchidquery".equals(type)) {
                originalData = CustomerUtil.batchidQueryRequestToXml(CustomerUtil.getBatchidQueryRequest(dealInfo));
            } else if ("fo.batch.settlement.pay".equals(type)) {
                originalData = CustomerUtil.batchSettlementApplyRequestToXml(CustomerUtil.getBatchSettlementApplyRequest(dealInfo));
            }
            WriteBankLogLn("发送银行的报文原始数据：" + originalData);
            byte[] orc = gzip(originalData.getBytes(ENCODING));
            byte[] randomBytes = randomKey();
            // 签名
            byte[] signBytes = signByRSA(orc, actItem);
            String signData = Base64.encodeBase64String(signBytes);

            // 加密
            String encryptData = AESHelper.encodeAES(randomBytes, orc).replaceAll("\r\n", "");

            // 数字信封
            byte[] digitalBytes = encryptByPKRSA(randomBytes, actItem);
            String digitalData = Base64.encodeBase64String(digitalBytes);

            sealdata.setOriginalData(originalData);
            sealdata.setEncryptedData(encryptData);
            sealdata.setDigitalEnvelope(digitalData);
            sealdata.setSignedData(signData);
            body.setData(sealdata);
            request.setRequestBody(body);
            postContent = CustomerUtil.settlementPkiApiRequestToXml(request);
            WriteBankLogLn("发送银行的报文：" + postContent);
            return postContent;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 用于把请求信息发送给快钱的webservices服务，同时拿到对应的应答信息
     */
    public String doit(String request, String url) {
        String response = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            //创建URL
            URL urlString = new URL(url);
            URLConnection urlConn = urlString.openConnection();
            urlConn.setRequestProperty("content-type", "text/xml;charset=utf-8");
            urlConn.setDoOutput(true);
            urlConn.setReadTimeout(1200000);
            PrintWriter out = new PrintWriter(urlConn.getOutputStream());
            if (request == null) {
                return null;
            }
            out.print(request);
            out.close();
            urlConn.connect();

            //*获取服务器端返回信息*//*
            isr = new InputStreamReader(urlConn.getInputStream(), "utf-8"); //解决乱码错配合61行
            StringBuffer sb = new StringBuffer();
            if (isr != null) {
                br = new BufferedReader(isr);
                String inputLine = "";
                while ((inputLine = br.readLine()) != null) {
                    sb.append(inputLine);
                }
            }
            String sbr = new String(sb.toString().getBytes());

            if (sbr.length() > 0) {
                response = StringUtils.ResFormat(sbr);
            }
        } catch (MalformedURLException e) {
            WriteBankLogLn(e);
        } catch (UnsupportedEncodingException e) {
            WriteBankLogLn(e);
        } catch (IOException e) {
            WriteBankLogLn(e);
        }
        return response;
    }

}
